/*
 * @author       : Zy
 * @Description  : 一个按键库，外部中断触发，可自由拓展按键，自定义按键值
 * @Date         : 2025-04-24 19:05:45
 * @LastEditTime : 2025-07-09 05:24:19
 */
#include "key.h"
#include <stdio.h>
/*
使用教程，引用此库，cubemx里面打开按键中断，修改按键信息和.h里面的按键数量
直接根据全局变量value的值就可以判断是哪个按键按下
当然，此程序提供了更高级的办法，即注册按键回调函数，在回调函数里面执行，事件驱动
回调函数使用：
    1.定义函数：
    eg:
    void MyKeyCallback(char key) {
        printf("按键值: %c\n", key);
    }
    2.注册回调函数,将函数绑定
    Keypad_RegisterCallback(MyKeyCallback);
*/
char value = '0';

KeyCallback keyCallback = NULL; // 声明一个指向回调函数的指针，默认回调为空
// 所有按键信息数组
Key_t keys[NUM_KEYS] = {
    {GPIOB, GPIO_PIN_10, 'W'}, // KEY1
    {GPIOA, GPIO_PIN_7, 'A'},  // KEY2
    {GPIOB, GPIO_PIN_14, 'X'}, // KEY3
    {GPIOA, GPIO_PIN_6, 'D'},  // KEY4
    {GPIOB, GPIO_PIN_13, 'S'}, // KEY5
};

void Keypad_RegisterCallback(KeyCallback callback)
{
    keyCallback = callback; // 将传入的回调函数指针赋值给 keyCallback
}

// 统一中断回调
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    // usart_printf("exit has in\n");
    for (int i = 0; i < NUM_KEYS; ++i)
    {
        // 判断触发中断的总线和按键此时是否为低电平
        if (GPIO_Pin == keys[i].pin &&
            HAL_GPIO_ReadPin(keys[i].port, keys[i].pin) == GPIO_PIN_RESET)
        {
            value = keys[i].key_val;
            // keyCallback(value);  // 如果回调函数已经注册，就调用它并传递按键值
            // usart_printf("Key is : %c\n", value);
            break;
        }
    }
}
